package com.smyx.reflect;

import com.smyx.bean.Student;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

public class ReflectDemo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 反射获取类的途径1 类名.class
        Class<Student> aClass1 = Student.class;
        System.out.println("类名.class >>> " + aClass1);
        // 反射获取类的途径2 类名.getClass()
        Class<? extends Student> aClass2 = Student.class;
        System.out.println("类名.getClass() >>> " + aClass2);
        // 反射获取类的途径3(需要抛出异常) Class.forName(全限定类名)
        Class<?> aClass3 = Class.forName("com.smyx.bean.Student");
        System.out.println("Class.forName(全限定类名) >>> " + aClass3);

        System.out.println("===================================================================");

        System.out.println("获取全限定的类名(包括包名)，即类的完整名字 >>> " + aClass1.getName());
        System.out.println("获取全限定的类名(包括包名) >>> " + aClass1.getCanonicalName());
        System.out.println("获取类名(不包括包名) >>> " + aClass1.getSimpleName());
        System.out.println("判断Class对象是否是表示一个接口 >>> " + aClass1.isInterface());
        System.out.println("返回Class对象数组，表示Class对象所引用的类所实现的所有接口 >>> " + Arrays.toString(aClass1.getInterfaces()));
        System.out.println("返回Class对象，表示Class对象所引用的类所继承的直接基类。应用该方法可在运行时发现一个对象完整的继承结构 >>> " + aClass1.getSuperclass());

        System.out.println("返回一个Object对象，是实现“虚拟构造器”的一种途径。使用该方法创建的类，必须带有无参的构造器 >>> ");
        aClass1.getDeclaredConstructor().newInstance();

        System.out.println("获得某个类的所有的公共（public）的字段，包括继承自父类的所有公共字段。类似的还有getMethods和getConstructors >>> ");
        Field[] fields = aClass1.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("获得某个类的自己声明的字段，即包括public、private和protected，默认但是不包括父类声明的任何字段。类似的还有getDeclaredMethods和getDeclaredConstructors >>> ");
        Field[] declaredFields = aClass1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
    }

}
